//编写一个方法，找出两个数字a和b中最大的那一个。不得使用if-else或其他比较运算符。 
// 示例： 
// 输入： a = 1, b = 2
//输出： 2
// 
//
// Related Topics 位运算 脑筋急转弯 数学 👍 158 👎 0


package LeetCode.editor.cn;

/**
 * @author ldltd
 * @date 2025-09-06 13:38:58
 * @description 面试题 16.07.最大数值
 */
public class MaximumLcci{
	 public static void main(String[] args) {
	 	 //测试代码
	 	 MaximumLcci fun=new MaximumLcci();
	 	 Solution solution = fun.new Solution();

	 }
	 
//力扣代码
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
		 /*
1.a - b的结果, 进行移位, 取符号位, 0说明结果是正数, a > b, 1说明结果是负数, a < b
2.(a+b)/2 + |(a-b)/2| 或者 (a+b)/2 - |(a-b)/2| , 前者可以取得较大的值, 后者取得较小的值, 很容易数学上证明
3.分配一个长度为a的数组array[a], 判断array[b]是否越界, 越界在java中会抛出异常
		 * */
	public int maximum1(int a, int b) {
		long val = (long )a-(long)b;
		int[] r=new int[]{a,b};
		//负数的最符号位是1，使用无符号位移，高位补0,直接把数移成1或者0，然后直接作为结果的索引
		return r[(int)(val>>>63)];
	}
	/**
	 * 比较符号位 0表示a>b, 1表示a<b
	 * @param a
	 * @param b
	 * @return
	 */
	public  int compare1(int a, int b) {
		// >> 带符号的右移, >>> 无符号的右移
//      return (((a - b) & 0x80000000) >> 31); // 判断符号位, a<b时为-1, 因为>>是带符号的右移, 保留了原来结果的符号位
		return (((a - b) & 0x80000000) >>> 31); // 判断符号位
	}


	/**
	 * 返回a和b中较大的数
	 * @param a
	 * @param b
	 * @return
	 */
	public  int compare2(int a, int b) {
		double x = (double)a;
		double y = (double)b;
		return (int)((x+y)/2 + Math.abs((x-y)/2)); // 判断符号位 但是用了Math.abs
	}

	/**
	 * 返回a和b中较小的数
	 * @param a
	 * @param b
	 * @return
	 */
	public  int compare3(int a, int b) {
		double x = (double)a;
		double y = (double)b;
		return (int)((x+y)/2 - Math.abs((x-y)/2)); // 判断符号位
	}

	/**
	 * 通过数组越界来判断
	 * @param a
	 * @param b
	 * @return
	 */
	public  int compare4(int a, int b) {
		int[] array = new int[a];
		try {
			array[b] = 0; // b>a的话, 会越界, 报异常
		} catch (ArrayIndexOutOfBoundsException e) {
			return b;
		}
		return a;
	}

	long absolute(long a) {
		long flag = a >> 63; //正数flag = 0，负数flag = -1
		return (flag ^ a) - flag; //任何数与0异或值不变，任何数与-1异或等价于按位取反
	}
	public int maximum(int a, int b) {
		// double c = a;
		// double d = b;
		// int res = (int) ((Math.abs(c-d) + c + d)/2);
		// return res;

		long c = a;
		long d = b;
//		int res = (int) ((Math.abs(c-d) + c + d)/2);
		int res= (int) ((absolute(c-d) + c + d)/2);
		return res;
	}

}
//leetcode submit region end(Prohibit modification and deletion)

}
